Manejo y visualización de datos

Crear código en R, uso colaborativo y reproducible

Manejo de datos

La exploración de datos nos permite verificar su calidad, entender los datos con los que trabajamos. Visualizar nuestros datos es un buen comienzo, pero a menudo vamos a necesitar transformar los datos previamente.

Formato tidy data

Cada variable tiene su propia columna Cada observación tiene su propia fila Cada valor tiene su propia celda

Ejemplo organización “tidy”

Buenas prácticas en el manejo de datos

  • Las variables van en columnas (e.g. mediciones: altura, peso, sexo)
  • Las observaciones cada una en una fila (e.g. individuos de pingüinos)
  • Evitar espacios, números, y caracteres especiales en los nombres de columnas.
  • Siempre anotar valores de cero, para diferenciarlos de datos faltantes.
  • Usar celdas vacías o con NA para datos faltantes.
  • Las fechas incluirlas en columnas separadas como year, month, day.
  • No combinar varias informaciones en una misma celda.
  • Realiza todas las manipulaciones de datos mediante código para dejar constancia de los cambios.
  • Exporta los datos como texto plano (txt, csv)

Ejemplo datos de pingüinos

# 1. Cargar librerías

library(dplyr)
library(ggplot2)
library(readr)
library(palmerpenguins)

# 2. Leer datos
data(package = 'palmerpenguins')
datos <- penguins

# 3. Explorar

head(datos)
# A tibble: 6 × 8
  species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
  <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
1 Adelie  Torgersen           39.1          18.7               181        3750
2 Adelie  Torgersen           39.5          17.4               186        3800
3 Adelie  Torgersen           40.3          18                 195        3250
4 Adelie  Torgersen           NA            NA                  NA          NA
5 Adelie  Torgersen           36.7          19.3               193        3450
6 Adelie  Torgersen           39.3          20.6               190        3650
# ℹ 2 more variables: sex <fct>, year <int>
unique(datos$island)
[1] Torgersen Biscoe    Dream    
Levels: Biscoe Dream Torgersen
datos %>% filter(year == 2007)
# A tibble: 110 × 8
   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
 1 Adelie  Torgersen           39.1          18.7               181        3750
 2 Adelie  Torgersen           39.5          17.4               186        3800
 3 Adelie  Torgersen           40.3          18                 195        3250
 4 Adelie  Torgersen           NA            NA                  NA          NA
 5 Adelie  Torgersen           36.7          19.3               193        3450
 6 Adelie  Torgersen           39.3          20.6               190        3650
 7 Adelie  Torgersen           38.9          17.8               181        3625
 8 Adelie  Torgersen           39.2          19.6               195        4675
 9 Adelie  Torgersen           34.1          18.1               193        3475
10 Adelie  Torgersen           42            20.2               190        4250
# ℹ 100 more rows
# ℹ 2 more variables: sex <fct>, year <int>
datos %>% filter(year == 2007, sex=="female")
# A tibble: 51 × 8
   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
 1 Adelie  Torgersen           39.5          17.4               186        3800
 2 Adelie  Torgersen           40.3          18                 195        3250
 3 Adelie  Torgersen           36.7          19.3               193        3450
 4 Adelie  Torgersen           38.9          17.8               181        3625
 5 Adelie  Torgersen           41.1          17.6               182        3200
 6 Adelie  Torgersen           36.6          17.8               185        3700
 7 Adelie  Torgersen           38.7          19                 195        3450
 8 Adelie  Torgersen           34.4          18.4               184        3325
 9 Adelie  Biscoe              37.8          18.3               174        3400
10 Adelie  Biscoe              35.9          19.2               189        3800
# ℹ 41 more rows
# ℹ 2 more variables: sex <fct>, year <int>
datos %>% filter(year == 2007, sex=="female", island %in% c("Dream", "Bicoe")) # island == c("Dream", "Bicoe")) NO VALE!
# A tibble: 22 × 8
   species   island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
   <fct>     <fct>           <dbl>         <dbl>             <int>       <int>
 1 Adelie    Dream            39.5          16.7               178        3250
 2 Adelie    Dream            39.5          17.8               188        3300
 3 Adelie    Dream            36.4          17                 195        3325
 4 Adelie    Dream            42.2          18.5               180        3550
 5 Adelie    Dream            37.6          19.3               181        3300
 6 Adelie    Dream            36.5          18                 182        3150
 7 Adelie    Dream            36            18.5               186        3100
 8 Adelie    Dream            37            16.9               185        3000
 9 Adelie    Dream            36            17.9               190        3450
10 Chinstrap Dream            46.5          17.9               192        3500
# ℹ 12 more rows
# ℹ 2 more variables: sex <fct>, year <int>

Limpiar los datos

Transformar variables

Ejemplo datos inscripción curso

library(here)
library(tidyverse)
library(tm)
library(wordcloud2)
library(readxl)

# se puede importar tablas desde excel, csv, ggsheets, txt...

datos_curso = read_excel(here("data/datos-curso.xlsx"))

# Vemos un resumen
str (datos_curso)
tibble [19 × 15] (S3: tbl_df/tbl/data.frame)
 $ Id                                                                    : num [1:19] 1 2 3 4 5 6 7 8 9 10 ...
 $ Hora de inicio                                                        : POSIXct[1:19], format: "2025-10-14 08:29:14" "2025-10-14 08:42:03" ...
 $ Hora de finalización                                                  : POSIXct[1:19], format: "2025-10-14 08:37:19" "2025-10-14 08:44:21" ...
 $ Correo electrónico                                                    : chr [1:19] "anonymous" "anonymous" "anonymous" "anónimo" ...
 $ Nombre                                                                : logi [1:19] NA NA NA NA NA NA ...
 $ Comentarios: DNI o documento                                          : logi [1:19] NA NA NA NA NA NA ...
 $ Curso de la primera matrícula en el programa de doctorado             : chr [1:19] "2024-25" "2023-24" "2022-23" "2023-24" ...
 $ Puntos: Curso de la primera matrícula en el programa de doctorado     : num [1:19] 0 0 0 NA NA NA NA NA NA NA ...
 $ Comentarios: Curso de la primera matrícula en el programa de doctorado: logi [1:19] NA NA NA NA NA NA ...
 $ Cuéntanos tu experiencia con R                                        : chr [1:19] "He usado R ya en anteriores ocasiones, tengo una pequeña base de conocimientos y estoy familiarizada con el lenguaje." "Usé R en el máster y para hacer algunos gráficos durante el principio de la tesis, pero me falta mucha segurida"| __truncated__ "Para mi tesis en el programa he debido desarrollar un Tn-seq, personalmente me ha costado horas de trabajo crea"| __truncated__ "He utilizado R en algunas asignaturas del grado y del máster, pero de una manera superficial." ...
 $ Puntos: Cuéntanos tu experiencia con R                                : num [1:19] 0 0 0 NA NA NA NA NA NA NA ...
 $ Comentarios: Cuéntanos tu experiencia con R                           : logi [1:19] NA NA NA NA NA NA ...
 $ Observaciones                                                         : chr [1:19] NA NA NA NA ...
 $ Puntos: Observaciones                                                 : num [1:19] 0 0 0 NA NA NA NA NA NA NA ...
 $ Comentarios: Observaciones                                            : logi [1:19] NA NA NA NA NA NA ...
#View (datos_curso) # Se nos abre en Rstudio

# seleccionamos columnas de un dataframe con $
datos_curso$`Hora de inicio`
 [1] "2025-10-14 08:29:14 UTC" "2025-10-14 08:42:03 UTC"
 [3] "2025-10-14 08:40:20 UTC" "2025-10-14 09:48:46 UTC"
 [5] "2025-10-14 09:52:44 UTC" "2025-10-14 10:37:18 UTC"
 [7] "2025-10-14 11:03:08 UTC" "2025-10-14 11:06:44 UTC"
 [9] "2025-10-14 11:40:51 UTC" "2025-10-14 13:03:53 UTC"
[11] "2025-10-14 13:50:48 UTC" "2025-10-14 14:06:02 UTC"
[13] "2025-10-14 14:41:19 UTC" "2025-10-14 15:00:44 UTC"
[15] "2025-10-15 16:50:04 UTC" "2025-10-15 21:43:56 UTC"
[17] "2025-10-20 15:49:58 UTC" "2025-10-22 17:32:48 UTC"
[19] "2025-10-28 12:22:05 UTC"
 [1] "Id"                                                                    
 [2] "Hora de inicio"                                                        
 [3] "Hora de finalización"                                                  
 [4] "Correo electrónico"                                                    
 [5] "Nombre"                                                                
 [6] "Comentarios: DNI o documento"                                          
 [7] "Curso de la primera matrícula en el programa de doctorado"             
 [8] "Puntos: Curso de la primera matrícula en el programa de doctorado"     
 [9] "Comentarios: Curso de la primera matrícula en el programa de doctorado"
[10] "Cuéntanos tu experiencia con R"                                        
[11] "Puntos: Cuéntanos tu experiencia con R"                                
[12] "Comentarios: Cuéntanos tu experiencia con R"                           
[13] "Observaciones"                                                         
[14] "Puntos: Observaciones"                                                 
[15] "Comentarios: Observaciones"                                            
datos_curso_filtrado <- datos_curso |>
  rename (curso = "Curso de la primera matrícula en el programa de doctorado",
         experiencia = "Cuéntanos tu experiencia con R",
         comentarios = "Observaciones",
         email = "Correo electrónico") |>
  select (curso, experiencia, comentarios, email) |>
  mutate (email = str_replace(email, "anonymous", "anónimo")) |>
  filter (curso == "2022-23")
  
words <- tolower(
                unlist(
                  strsplit(datos_curso_filtrado$experiencia, " ") ) ) 

words <- gsub("[[:punct:][:digit:]]", "",words)
stop_es <- stopwords("spanish")
words_clean <- words[!words %in% stop_es]

# Plot
wordcloud2(data=table(words_clean), size=0.5,
           color = rep(RColorBrewer::brewer.pal(11, "PRGn"), 20))

Visualizacion de datos

DATA VIZZZZZZ

Desde gráficos muy simples

plot(x=rnorm(100), y=rnorm(100))

Hasta gráficos muy complejos

quién habla con quién en “The Office” Código

Datos georeferenciados

library(rgbif)
library(ggplot2)
library(rnaturalearth)
library(sf)

datos <- occ_search(scientificName = "Lynx pardinus", limit = 100)
#head(datos$data[, c("species", "decimalLatitude", "decimalLongitude")])
df <- datos$data

# Basic map
world <- ne_countries(scale = "medium", returnclass = "sf")

# Plot
ggplot() +
  geom_sf(data = world, fill = "black", color = "grey30") +
  geom_point(data = df, aes(x = decimalLongitude, y = decimalLatitude),
             color = "darkred", size = 2, alpha = 0.7) +
  coord_sf() +
  theme_minimal()

# Basic map
spain <- ne_countries(country=c("spain", "portugal"))
plot(spain)

# Plot

ggplot() +
  geom_sf(data = spain, fill = "grey99", color = "grey30") +
  geom_point(data = df, aes(x = decimalLongitude, y = decimalLatitude),
             color = "darkgreen", size = 2, alpha = 0.7) +
  coord_sf() +
  theme_minimal()

Mapa plantas

library(FloraIberica)
map_distribution(genus = "Lavandula", species = "stoechas", size = 0.9)

Visualizaciones geniales

Valentina de Filippo

Bibliografía

https://www.tandfonline.com/doi/full/10.1080/00031305.2017.1375989#d1e199